From f82898f393636422c09c18fa4d62dab782dc545b Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Sun, 9 Jun 2019 02:21:05 +0000 Subject: [PATCH] model button: Make left/right switch submenus This is expected menu keynav behavior: If the focused item has a submenu, open it on right arrow press. And if we are in a submenu title, make left arrow press close it. --- gtk/gtkmodelbutton.c | 65 +++++++++++++++++++++++++++++++++++++------- 1 file changed, 55 insertions(+), 10 deletions(-) diff --git a/gtk/gtkmodelbutton.c b/gtk/gtkmodelbutton.c index 5bb6b3c48c..ede101df55 100644 --- a/gtk/gtkmodelbutton.c +++ b/gtk/gtkmodelbutton.c @@ -870,6 +870,26 @@ gtk_model_button_destroy (GtkWidget *widget) GTK_WIDGET_CLASS (gtk_model_button_parent_class)->destroy (widget); } +static void +switch_menu (GtkModelButton *button) +{ + GtkWidget *stack; + + stack = gtk_widget_get_ancestor (GTK_WIDGET (button), GTK_TYPE_STACK); + if (stack != NULL) + gtk_stack_set_visible_child_name (GTK_STACK (stack), button->menu_name); +} + +static void +close_menu (GtkModelButton *button) +{ + GtkWidget *popover; + + popover = gtk_widget_get_ancestor (GTK_WIDGET (button), GTK_TYPE_POPOVER); + if (popover != NULL) + gtk_popover_popdown (GTK_POPOVER (popover)); +} + static void gtk_model_button_clicked (GtkButton *button) { @@ -877,19 +897,11 @@ gtk_model_button_clicked (GtkButton *button) if (model_button->menu_name != NULL) { - GtkWidget *stack; - - stack = gtk_widget_get_ancestor (GTK_WIDGET (button), GTK_TYPE_STACK); - if (stack != NULL) - gtk_stack_set_visible_child_name (GTK_STACK (stack), model_button->menu_name); + switch_menu (model_button); } else if (model_button->role == GTK_BUTTON_ROLE_NORMAL) { - GtkWidget *popover; - - popover = gtk_widget_get_ancestor (GTK_WIDGET (button), GTK_TYPE_POPOVER); - if (popover != NULL) - gtk_popover_popdown (GTK_POPOVER (popover)); + close_menu (model_button); } } @@ -943,6 +955,38 @@ gtk_model_button_map (GtkWidget *widget) } } +static gboolean +gtk_model_button_focus (GtkWidget *widget, + GtkDirectionType direction) +{ + GtkModelButton *button = GTK_MODEL_BUTTON (widget); + + if (gtk_widget_is_focus (widget)) + { + if (direction == GTK_DIR_LEFT && + button->role == GTK_BUTTON_ROLE_TITLE && + button->menu_name != NULL) + { + switch_menu (button); + return TRUE; + } + else if (direction == GTK_DIR_RIGHT && + button->role == GTK_BUTTON_ROLE_NORMAL && + button->menu_name != NULL) + { + switch_menu (button); + return TRUE; + } + } + else + { + gtk_widget_grab_focus (widget); + return TRUE; + } + + return FALSE; +} + static void gtk_model_button_class_init (GtkModelButtonClass *class) { @@ -960,6 +1004,7 @@ gtk_model_button_class_init (GtkModelButtonClass *class) widget_class->map = gtk_model_button_map; widget_class->state_flags_changed = gtk_model_button_state_flags_changed; widget_class->direction_changed = gtk_model_button_direction_changed; + widget_class->focus = gtk_model_button_focus; button_class->clicked = gtk_model_button_clicked; -- 2.30.2